#include <odb/tracer.hxx>
#include <odb/forward.hxx>
#include <odb/statement.hxx>
#include <odb/database.hxx>
#include <odb/mysql/database.hxx>
#include "class-odb.hxx"
#include "class.hxx"
#include <gflags/gflags.h>

DEFINE_int32(max_pool,3,"这是MySQL连接池最大连接数量");
DEFINE_string(user,"root","这是访问MySQL用户名");
DEFINE_string(password,"123456","这是MySQL密码");
DEFINE_string(db,"TESTDB","数据库默认名称");
DEFINE_string(host,"127.0.0.1","MySQL服务器地址");
DEFINE_int32(port,0,"这是MySQL数据库端口号");
DEFINE_string(charset,"utf8","MySQL客户端的编码方式");

// class mytracer : public odb::mysql::tracer {
//     public:
//     virtual void execute (odb::mysql::connection&, const char* statement) {
//         std::cout << "exec sql:[" << statement << "]" <<std::endl;
//     }
// };
void insert_classes(odb::mysql::database& db)
{
    try
    {
        //开启事务，获取事务对象
        odb::transaction trans(db.begin());
        Classes c11("一年级一班");
        Classes c12("一年级二班");
        db.persist(c11);
        db.persist(c12);
        trans.commit();
    }catch(std::exception& e)
    {
        std::cout<<"insert_classes err:"<<e.what()<<std::endl;
    }
}
void insert_student(odb::mysql::database& db)
{
    try
    {
        //开启事务，获取事务对象
        odb::transaction trans(db.begin());
        Student s1(1,"张三",2);
        Student s2(2,"李四",3);
        db.persist(s1);
        db.persist(s2);
        trans.commit();
    }catch(std::exception& e)
    {
        std::cout<<"insert_student err:"<<e.what()<<std::endl;
    }
}
Classes select_classes(odb::mysql::database& db)
{
    Classes cla;
    try
    {
        //开启事务，获取事务对象
        odb::transaction trans(db.begin());
        odb::query<Classes> cond(odb::query<Classes>::id==3);

        odb::result<Classes> ret(db.query<Classes>(cond));
        std::cout<<"查询到的数量:"<<ret.size()<<std::endl;
        if(ret.size())
        cla = *ret.begin();
        trans.commit();
    }catch(std::exception& e)
    {
        std::cout<<"select_classes err:"<<e.what()<<std::endl;
    }
    return cla;

};
void update_classes(odb::mysql::database& db,Classes& classes)
{
    try
    {
        //开启事务，获取事务对象
        odb::transaction trans(db.begin());
        classes.name("一年级三班");
        db.update(classes);
        trans.commit();
    }catch(std::exception& e)
    {
        std::cout<<"update_classes err:"<<e.what()<<std::endl;
    }
}
void remove_classes(odb::mysql::database& db)
{
    try
    {
        //开启事务，获取事务对象
        odb::transaction trans(db.begin());
        db.erase_query<Classes>(odb::query<Classes>::id==3);
        trans.commit();
    }catch(std::exception& e)
    {
        std::cout<<"remove_classes err:"<<e.what()<<std::endl;
    }
}
void query_all_name(odb::mysql::database& db)//测试视图查询
{
    try
    {
        //开启事务，获取事务对象
        odb::transaction trans(db.begin());
        typedef odb::query<Student> query;
        typedef odb::result<all_name> result;
        query cond();
        result ret(db.query<all_name>(cond));
        for(auto it=ret.begin();it!=ret.end();it++)
            std::cout<<"all_name:"<<it->n<<std::endl;
        trans.commit();
    }catch(std::exception& e)
    {
        std::cout<<"query_all_name err:"<<e.what()<<std::endl;
    }
}
void query_classes_student(odb::mysql::database& db)
{
    try
    {
        //开启事务，获取事务对象
        odb::transaction trans(db.begin());
        typedef odb::result<classes_student> result;
        typedef odb::query<classes_student> query;
        result ret(db.query<classes_student>());
        for(auto e:ret)
        {
            std::cout<<"query_classes_student查询结果为:"<<e.id<<" "<<e.name<<" "<<*e.year<<" "<<e.classes_name<<std::endl;
        }
        trans.commit();
    }catch(std::exception& e)
    {
        std::cout<<"query_classes_student err:"<<e.what()<<std::endl;
    }
}
int main(int argc,char* argv[])
{
    google::ParseCommandLineFlags(&argc, &argv, true);
    //1.构造连接池工厂实例，并配置连接池工厂
    auto cpf = std::make_unique<odb::mysql::connection_pool_factory>(FLAGS_max_pool,0);
    //2.构建数据库操作对象
    //database (const char* user,
    //          const char* passwd,
    //          const char* db,
    //          const char* host = 0,
    //          unsigned int port = 0,
    //          const char* socket = 0,
    //          const char* charset = 0,
    //          unsigned long client_flags = 0,
    //          details::transfer_ptr<connection_factory> =
    //          details::transfer_ptr<connection_factory> ());
    odb::mysql::database db(FLAGS_user, FLAGS_password, FLAGS_db,FLAGS_host, FLAGS_port, 
    "", FLAGS_charset,0, std::move(cpf));
    //insert_classes(db);
    query_all_name(db);
     //query_classes_student(db);
}